package com.trace.demo.controller;

import com.trace.demo.entity.FarmingActivity;
import com.trace.demo.entity.TodoItem;
import com.trace.demo.entity.User;
import com.trace.demo.entity.Product;
import com.trace.demo.entity.TraceCode;
import com.trace.demo.entity.FarmingInfo;
import com.trace.demo.entity.Order;
import com.trace.demo.repository.*;
import com.trace.demo.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 统计控制器
 */
@RestController
@RequestMapping("/api/statistics")
public class StatisticsController {

    private final UserRepository userRepository;
    private final ProductRepository productRepository;
    private final FarmingInfoRepository farmingInfoRepository;
    private final FarmingActivityRepository activityRepository;
    private final TodoItemRepository todoItemRepository;
    private final TraceCodeRepository traceCodeRepository;
    private final TraceQueryLogRepository traceQueryLogRepository;
    private final OrderRepository orderRepository;

    @Autowired
    public StatisticsController(UserRepository userRepository,
                               ProductRepository productRepository,
                               FarmingInfoRepository farmingInfoRepository,
                               FarmingActivityRepository activityRepository,
                               TodoItemRepository todoItemRepository,
                               TraceCodeRepository traceCodeRepository,
                               TraceQueryLogRepository traceQueryLogRepository,
                               OrderRepository orderRepository) {
        this.userRepository = userRepository;
        this.productRepository = productRepository;
        this.farmingInfoRepository = farmingInfoRepository;
        this.activityRepository = activityRepository;
        this.todoItemRepository = todoItemRepository;
        this.traceCodeRepository = traceCodeRepository;
        this.traceQueryLogRepository = traceQueryLogRepository;
        this.orderRepository = orderRepository;
    }

    /**
     * 获取系统概览 - 前端调用的端点
     * @return 系统概览数据
     */
    @GetMapping("/overview")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getOverview() {
        return getSystemOverview(); // 复用现有方法
    }

    /**
     * 获取系统概览
     * @return 系统概览数据
     */
    @GetMapping("/system-overview")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getSystemOverview() {
        Map<String, Object> overview = new HashMap<>();

        // 用户数量统计
        long totalUsers = userRepository.count();
        long farmersCount = userRepository.countByRole(User.UserRole.FARMER);
        long dealersCount = userRepository.countByRole(User.UserRole.DEALER);
        long adminsCount = userRepository.countByRole(User.UserRole.ADMIN);

        // 产品和追溯码统计
        long productsCount = productRepository.count();
        long traceCodesCount = traceCodeRepository.count();

        // 扫码次数统计
        long scanCount = traceQueryLogRepository.count();
        // 如果没有记录，返回模拟值
        if (scanCount == 0) {
            scanCount = 2356;
        }

        // 今日扫码次数
        long todayScanCount = traceQueryLogRepository.countByScanTimeAfter(
                LocalDateTime.now().toLocalDate().atStartOfDay());


        // 种植信息统计
        long farmingInfoCount = farmingInfoRepository.count();

        Map<String, Object> usersStats = new HashMap<>();
        usersStats.put("total", totalUsers);
        usersStats.put("farmers", farmersCount);
        usersStats.put("dealers", dealersCount);
        usersStats.put("admins", adminsCount);

        Map<String, Object> productsStats = new HashMap<>();
        productsStats.put("total", productsCount);
        productsStats.put("traceCodes", traceCodesCount);

        Map<String, Object> scanningStats = new HashMap<>();
        scanningStats.put("total", scanCount);
        scanningStats.put("today", todayScanCount);

        Map<String, Object> farmingStats = new HashMap<>();
        farmingStats.put("total", farmingInfoCount);

        overview.put("users", usersStats);
        overview.put("products", productsStats);
        overview.put("scanning", scanningStats);
        overview.put("farming", farmingStats);

        return ResponseEntity.ok(new ApiResponse<>(true, "System overview statistics retrieved successfully", overview));
    }

    /**
     * 获取溯源查询地理位置分布
     * @return 地理位置分布数据
     */
    @GetMapping("/trace-query-locations")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getTraceQueryLocations() {
        Map<String, Object> result = new HashMap<>();

        // 尝试从数据库获取按地理位置分组的统计
        List<Map<String, Object>> locationStats = traceQueryLogRepository.countByLocation();

        // 如果没有数据，生成模拟数据
        if (locationStats.isEmpty()) {
            // 创建模拟数据
            List<Map<String, Object>> mockLocationData = new ArrayList<>();

            String[] majorCities = {
                "北京", "上海", "广州", "深圳", "杭州",
                "成都", "重庆", "西安", "南京", "武汉"
            };

            Random random = new Random();
            int baseCount = 50;

            for (String city : majorCities) {
                Map<String, Object> locationData = new HashMap<>();
                locationData.put("name", city);
                // 生成一个随机的查询次数
                locationData.put("value", baseCount + random.nextInt(baseCount));
                mockLocationData.add(locationData);
            }

            result.put("locations", mockLocationData);
        } else {
            result.put("locations", locationStats);
        }

        return ResponseEntity.ok(new ApiResponse<>(true, "Trace query locations retrieved successfully", result));
    }

    /**
     * 获取最常查询的产品
     * @param limit 限制数量
     * @return 产品查询排行数据
     */
    @GetMapping("/top-queried-products")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getTopQueriedProducts(
            @RequestParam(defaultValue = "5") int limit) {
        Map<String, Object> result = new HashMap<>();

        // 尝试从数据库获取最常查询的产品
        List<Map<String, Object>> topProducts = traceQueryLogRepository.findTopProductsByQueryCount(limit);

        // 如果没有数据，尝试生成基于实际产品的模拟数据
        if (topProducts.isEmpty()) {
            List<Product> products = productRepository.findAll();

            if (!products.isEmpty()) {
                // 使用真实产品数据生成模拟查询统计
                topProducts = generateMockProductStatsFromRealProducts(products, limit);
            } else {
                // 完全模拟数据
                Map<String, Integer> mockData = new HashMap<>();
                mockData.put("枸杞干果", 200);
                mockData.put("枸杞汁", 150);
                mockData.put("枸杞茶", 100);
                mockData.put("枸杞粉", 80);
                mockData.put("其他枸杞产品", 50);

                // 将Map转换为与Repository返回格式一致的List<Map>
                topProducts = new ArrayList<>();
                int total = mockData.values().stream().mapToInt(Integer::intValue).sum();

                for (Map.Entry<String, Integer> entry : mockData.entrySet()) {
                    Map<String, Object> product = new HashMap<>();
                    product.put("productName", entry.getKey());
                    product.put("scanCount", entry.getValue());
                    product.put("ratio", Math.round((double)entry.getValue() / total * 1000) / 10.0); // 百分比，保留一位小数
                    topProducts.add(product);
                }
            }
        }

        result.put("products", topProducts);
        return ResponseEntity.ok(new ApiResponse<>(true, "Top queried products retrieved successfully", result));
    }

    /**
     * 生成模拟的产品统计数据（基于真实产品）
     */
    private List<Map<String, Object>> generateMockProductStatsFromRealProducts(List<Product> products, int limit) {
        List<Map<String, Object>> result = new ArrayList<>();
        int productsToUse = Math.min(limit, products.size());

        // 计算总数，用于计算百分比
        int total = 0;
        int[] counts = new int[productsToUse];

        for (int i = 0; i < productsToUse; i++) {
            // 使递减的值，模拟热度排行
            counts[i] = 100 - i * 10;
            if (counts[i] < 10) counts[i] = 10; // 确保至少有10次查询
            total += counts[i];
        }

        // 创建结果对象
        for (int i = 0; i < productsToUse; i++) {
            Product product = products.get(i);
            Map<String, Object> productData = new HashMap<>();
            productData.put("productName", product.getProductName());
            productData.put("scanCount", counts[i]);
            productData.put("ratio", Math.round((double)counts[i] / total * 1000) / 10.0); // 百分比，保留一位小数
            result.add(productData);
        }

        return result;
    }

    /**
     * 获取最近7天统计数据
     * @return 最近7天数据
     */
    @GetMapping("/last-7-days")
    public ResponseEntity<Map<String, Object>> getLast7DaysStatistics() {
        Map<String, Object> result = new HashMap<>();

        LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);

        // 过去7天的用户注册数
        List<User> newUsers = userRepository.findByCreatedAtAfter(sevenDaysAgo);
        result.put("newUserCount", newUsers.size());

        // 过去7天的活动数
        List<FarmingActivity> activities = activityRepository.findByTimestampAfter(sevenDaysAgo);
        result.put("activityCount", activities.size());

        // 按天统计活动
        Map<LocalDate, Long> dailyActivities = activities.stream()
                .collect(Collectors.groupingBy(
                        activity -> activity.getTimestamp().toLocalDate(),
                        Collectors.counting()
                ));

        // 填充过去7天的数据
        Map<String, Long> dailyStats = new LinkedHashMap<>();
        for (int i = 6; i >= 0; i--) {
            LocalDate date = LocalDate.now().minusDays(i);
            dailyStats.put(date.toString(), dailyActivities.getOrDefault(date, 0L));
        }
        result.put("dailyActivities", dailyStats);

        return ResponseEntity.ok(result);
    }

    /**
     * 获取用户角色分布
     * @return 用户角色分布数据
     */
    @GetMapping("/user-role-distribution")
    public ResponseEntity<Map<String, Long>> getUserRoleDistribution() {
        Map<String, Long> distribution = new HashMap<>();

        List<User> users = userRepository.findAll();
        Map<String, Long> roleCount = users.stream()
                .collect(Collectors.groupingBy(
                        user -> user.getRole().toString(),
                        Collectors.counting()
                ));

        // 确保所有角色都有数据
        distribution.put("ROLE_ADMIN", roleCount.getOrDefault("ROLE_ADMIN", 0L));
        distribution.put("ROLE_FARMER", roleCount.getOrDefault("ROLE_FARMER", 0L));
        distribution.put("ROLE_DEALER", roleCount.getOrDefault("ROLE_DEALER", 0L));

        return ResponseEntity.ok(distribution);
    }

    /**
     * 获取产品类别分布
     * @return 产品类别分布数据
     */
    @GetMapping("/product-category-distribution")
    public ResponseEntity<Map<String, Object>> getProductCategoryDistribution() {
        List<Map<String, Object>> categories = productRepository.countByCategories();
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        return ResponseEntity.ok(result);
    }

    /**
     * 获取农户统计数据
     * @param farmerId 农户ID
     * @return 农户统计数据
     */
    @GetMapping("/farmer/{farmerId}")
    public ResponseEntity<Map<String, Object>> getFarmerStats(@PathVariable Long farmerId) {
        Map<String, Object> stats = new HashMap<>();

        // 种植信息数量
        long infoCount = farmingInfoRepository.countByUserId(farmerId);
        stats.put("infoCount", infoCount);

        // 最近活动
        List<FarmingActivity> recentActivities = activityRepository
                .findByUserIdOrderByTimestampDesc(farmerId)
                .stream()
                .limit(5)
                .collect(Collectors.toList());
        stats.put("recentActivities", recentActivities);

        // 待办任务数量
        List<TodoItem> todoItems = todoItemRepository.findByUserId(farmerId);
        long completedTasks = todoItems.stream().filter(TodoItem::isCompleted).count();
        long pendingTasks = todoItems.size() - completedTasks;

        stats.put("completedTasks", completedTasks);
        stats.put("pendingTasks", pendingTasks);

        // 产品数量
        long productCount = productRepository.countByFarmerId(farmerId);
        stats.put("productCount", productCount);

        // 订单数量 (假设有订单功能)
        stats.put("orderCount", 0);

        // 溯源查询次数 (假设功能)
        stats.put("queryCount", 0);

        return ResponseEntity.ok(stats);
    }

    /**
     * 获取农户待办事项
     * @param farmerId 农户ID
     * @return 待办事项列表
     */
    @GetMapping("/farmer/{farmerId}/todos")
    public ResponseEntity<List<TodoItem>> getFarmerTodos(@PathVariable Long farmerId) {
        return ResponseEntity.ok(todoItemRepository.findByUserId(farmerId));
    }

    /**
     * 更新农户的待办事项列表
     * @param farmerId 农户ID
     * @param todosData 待办事项数据
     * @return 更新后的待办事项列表
     */
    @PutMapping("/farmer/{farmerId}/todos")
    @Transactional
    public ResponseEntity<?> updateFarmerTodos(
            @PathVariable Long farmerId,
            @RequestBody List<Map<String, Object>> todosData) {
        return userRepository.findById(farmerId)
                .map(farmer -> {
                    try {
                        List<TodoItem> newItems = new ArrayList<>();

                        for (Map<String, Object> item : todosData) {
                            TodoItem todoItem = new TodoItem();

                            // 设置基本属性
                            if (item.containsKey("content")) {
                                todoItem.setContent((String) item.get("content"));
                            }

                            // 设置完成状态
                            if (item.containsKey("completed")) {
                                Object completedValue = item.get("completed");

                                if (completedValue instanceof Boolean) {
                                    todoItem.setCompleted((Boolean) completedValue);
                                } else if (completedValue instanceof String) {
                                    // 转换String为Boolean
                                    String strValue = (String) completedValue;
                                    todoItem.setCompleted(Boolean.parseBoolean(strValue));
                                } else {
                                    // 默认为false
                                    todoItem.setCompleted(false);
                                }
                            } else {
                                todoItem.setCompleted(false);
                            }

                            // 设置创建时间
                            todoItem.setCreatedAt(LocalDateTime.now());

                            // 设置用户
                            todoItem.setUser(farmer);

                            newItems.add(todoItem);
                        }

                        // 保存所有新待办事项
                        List<TodoItem> savedItems = todoItemRepository.saveAll(newItems);

                        return ResponseEntity.ok(savedItems);
                    } catch (Exception e) {
                        return ResponseEntity.badRequest().body(createErrorMap("更新待办事项失败: " + e.getMessage()));
                    }
                })
                .orElse(ResponseEntity.badRequest().body(createErrorMap("User not found with id: " + farmerId)));
    }

    /**
     * 获取农户超时待办事项
     * @param farmerId 农户ID
     * @return 超时待办事项列表
     */
    @GetMapping("/farmer/{farmerId}/overdueTodos")
    public ResponseEntity<List<TodoItem>> getOverdueTodos(@PathVariable Long farmerId) {
        LocalDateTime now = LocalDateTime.now();
        List<TodoItem> overdueTodos = todoItemRepository.findByUserIdAndDueDateBeforeAndCompletedFalse(
                farmerId, now);
        return ResponseEntity.ok(overdueTodos);
    }

    /**
     * 获取经销商统计数据
     * @return 经销商统计数据
     */
    @GetMapping("/dealer/stats")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDealerStats() {
        try {
            Map<String, Object> stats = new HashMap<>();

            // 统计总订单数
            long totalOrders = orderRepository.count();
            stats.put("totalOrders", totalOrders);

            // 统计待处理订单数
            long pendingOrders = orderRepository.countByStatus(Order.OrderStatus.PENDING);
            stats.put("pendingOrders", pendingOrders);

            // 统计运输中订单数
            long shippingOrders = orderRepository.countByStatus(Order.OrderStatus.SHIPPED);
            stats.put("shippingOrders", shippingOrders);

            // 统计客户数量
            long customerCount = userRepository.countByUserType("CUSTOMER");
            stats.put("customerCount", customerCount);

            return ResponseEntity.ok(new ApiResponse<>(true, "获取统计数据成功", stats));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取统计数据失败: " + e.getMessage(), null));
        }
    }

    // 获取经销商销售数据
    @GetMapping("/dealer/sales")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getDealerSalesData(
            @RequestParam(defaultValue = "week") String period) {
        try {
            Map<String, Object> response = new HashMap<>();
            List<String> labels = new ArrayList<>();
            List<Double> values = new ArrayList<>();

            LocalDate endDate = LocalDate.now();
            LocalDate startDate;
            DateTimeFormatter formatter;

            // 根据周期设置开始日期和格式化器
            switch (period) {
                case "week":
                    startDate = endDate.minusWeeks(1);
                    formatter = DateTimeFormatter.ofPattern("MM-dd");
                    break;
                case "month":
                    startDate = endDate.minusMonths(1);
                    formatter = DateTimeFormatter.ofPattern("MM-dd");
                    break;
                case "year":
                    startDate = endDate.minusYears(1);
                    formatter = DateTimeFormatter.ofPattern("yyyy-MM");
                    break;
                default:
                    startDate = endDate.minusWeeks(1);
                    formatter = DateTimeFormatter.ofPattern("MM-dd");
            }

            // 生成日期标签
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                labels.add(date.format(formatter));

                // 查询该日期的订单总金额
                double dailySales = orderRepository.findByOrderDateBetween(
                        date.atStartOfDay(),
                        date.plusDays(1).atStartOfDay().minusNanos(1)
                ).stream()
                 .mapToDouble(Order::getTotalAmount)
                 .sum();

                values.add(dailySales);
            }

            response.put("labels", labels);
            response.put("values", values);

            return ResponseEntity.ok(new ApiResponse<>(true, "获取销售数据成功", response));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取销售数据失败: " + e.getMessage(), null));
        }
    }

    // 获取经销商产品分布
    @GetMapping("/dealer/products")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDealerProductDistribution() {
        try {
            List<Product> products = productRepository.findAll();
            Map<String, Long> categoryCount = products.stream()
                    .collect(Collectors.groupingBy(
                            Product::getCategory,
                            Collectors.counting()
                    ));

            List<Map<String, Object>> distribution = new ArrayList<>();
            categoryCount.forEach((category, count) -> {
                Map<String, Object> item = new HashMap<>();
                item.put("category", category);
                item.put("count", count);
                item.put("percentage", Math.round((count * 100.0) / products.size()));
                distribution.add(item);
            });

            return ResponseEntity.ok(new ApiResponse<>(true, "获取产品分布数据成功", distribution));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取产品分布数据失败: " + e.getMessage(), null));
        }
    }

    // 获取经销商待办任务
    @GetMapping("/dealer/{id}/todos")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDealerTodoTasks(
            @PathVariable Long id) {
        try {
            List<Map<String, Object>> todos = new ArrayList<>();

            // 获取待处理订单作为待办任务
            List<Order> pendingOrders = orderRepository.findByStatusAndDealerId(
                    Order.OrderStatus.PENDING, id);

            // 将待处理订单转换为待办任务
            for (Order order : pendingOrders) {
                Map<String, Object> todo = new HashMap<>();
                todo.put("id", order.getId());
                todo.put("content", "处理订单: " + order.getOrderNumber());
                todo.put("dueDate", LocalDateTime.now().plusDays(1).format(
                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                todo.put("priority", "medium");
                todos.add(todo);
            }

            // 获取已支付未发货订单作为待办任务
            List<Order> paidOrders = orderRepository.findByStatusAndDealerId(
                    Order.OrderStatus.PAID, id);

            // 将已支付未发货订单转换为待办任务
            for (Order order : paidOrders) {
                Map<String, Object> todo = new HashMap<>();
                todo.put("id", order.getId());
                todo.put("content", "发货订单: " + order.getOrderNumber());
                todo.put("dueDate", LocalDateTime.now().plusDays(1).format(
                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                todo.put("priority", "high");
                todos.add(todo);
            }

            return ResponseEntity.ok(new ApiResponse<>(true, "获取待办任务成功", todos));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取待办任务失败: " + e.getMessage(), null));
        }
    }

    // 获取最近订单
    @GetMapping("/recent-orders")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getRecentOrders() {
        try {
            // 获取最近5个订单
            List<Order> recentOrders = orderRepository.findTop5ByOrderByOrderDateDesc();
            List<Map<String, Object>> orderList = new ArrayList<>();

            for (Order order : recentOrders) {
                Map<String, Object> orderData = new HashMap<>();
                orderData.put("id", order.getId());
                orderData.put("orderNo", order.getOrderNumber());
                orderData.put("productName", order.getProductName());
                orderData.put("customerName", order.getCustomerName());
                orderData.put("orderDate", order.getOrderDate().format(
                        DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                orderData.put("status", order.getStatus());
                orderData.put("statusText", getStatusText(order.getStatus()));

                orderList.add(orderData);
            }

            return ResponseEntity.ok(new ApiResponse<>(true, "获取最近订单成功", orderList));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取最近订单失败: " + e.getMessage(), null));
        }
    }

    // 获取状态文本
    private String getStatusText(Order.OrderStatus status) {
        switch (status) {
            case PENDING:
                return "待处理";
            case PAID:
                return "已支付";
            case SHIPPED:
                return "已发货";
            case DELIVERED:
                return "已送达";
            case COMPLETED:
                return "已完成";
            case CANCELLED:
                return "已取消";
            default:
                return "未知";
        }
    }

    /**
     * 创建错误响应Map
     * @param errorMessage 错误信息
     * @return 错误响应Map
     */
    private Map<String, Object> createErrorMap(String errorMessage) {
        Map<String, Object> error = new HashMap<>();
        error.put("error", errorMessage);
        return error;
    }
}
